package com.tianhao.shell.service.impl;

import com.tianhao.shell.build.DefaultShutdown;
import com.tianhao.shell.build.DefaultStartUp;
import com.tianhao.shell.build.Director;
import com.tianhao.shell.build.ShutdownBuilder;
import com.tianhao.shell.constant.Constants;
import com.tianhao.shell.domain.ModelDomain;
import com.tianhao.shell.service.ShellService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

/**
 * @ClassName: ShellServiceImpl
 * @Description: 脚本下载实现
 * @author: tianhao.luo@hand-china.com
 * @date: 2020/11/4  11:30
 */
@Service
public class ShellServiceImpl implements ShellService {
    public static final String WRAP = "\n";

    @Autowired
    private DefaultStartUp defaultStartUp;

    @Override
    public void createStartupShell(ModelDomain modelDomain, HttpServletResponse httpServletResponse) {
        Assert.isTrue(!CollectionUtils.isEmpty(modelDomain.getModel()),"需要勾选模块再生成");
        //创建目录
        File file1 = new File(Constants.BASE_OUTPUT_PATH );
        if (!file1.exists()) {
            file1.mkdir();
        }
        FileWriter fileWriter = null;
        //获取勾选的模块
        List<String> modelList = modelDomain.getModel();
        for (String model :
                modelList) {
            try {

                if (!StringUtils.isEmpty(model)) {
                    String startUp = createStartUp(model,modelDomain);

                    File file = new File(Constants.BASE_OUTPUT_PATH + model + "-startup.sh");
                    fileWriter = new FileWriter(file);
                    fileWriter.write(startUp);
                    fileWriter.flush();

                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fileWriter != null) {
                    try {
                        fileWriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }
        }

    }

    @Override
    public void createShutDownShell(ModelDomain modelDomain, HttpServletResponse httpServletResponse) {
        Assert.isTrue(!CollectionUtils.isEmpty(modelDomain.getModel()),"需要勾选模块再生成");
        //创建目录
        File file1 = new File(Constants.BASE_OUTPUT_PATH);
        if (!file1.exists()) {
            file1.mkdir();
        }
        FileWriter fileWriter = null;
        // 获取模块
        List<String> modelList = modelDomain.getModel();
        for (String model :
                modelList) {
            try {
                if (!StringUtils.isEmpty(model)) {
                    //创建脚本
                    String startUp = createShutdown(model);

                    File file = new File(Constants.BASE_OUTPUT_PATH + model + "-shutdown.sh");
                    fileWriter = new FileWriter(file);
                    fileWriter.write(startUp);
                    fileWriter.flush();

                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fileWriter != null) {
                    try {
                        fileWriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }
        }
    }

    /**
     *
     * @param modelDomain         接收对象
     * @param httpServletResponse 响应
     */
    @Override
    public void createStartupShellAll(ModelDomain modelDomain, HttpServletResponse httpServletResponse) {
        // 生成启动模块目录
        List<String> modelList = modelDomain.getModel();
        StringBuilder sb = new StringBuilder();
        for (String model :
                modelList) {
            if (sb.length() == 0) {
                sb.append(model);
            } else {
                sb.append(" ").append(model);
            }
        }
        String dirNames = sb.toString();
        sb.setLength(0);
        //生成启动脚本
        sb.append("#!/bin/bash").append(WRAP)
                .append("path=").append(modelDomain.getPath()).append(WRAP)
                .append("dirnames=(").append(dirNames).append(")").append(WRAP)
                .append("for dir in ${dirnames[@]}").append(WRAP)
                .append("do").append(WRAP)
                .append("echo \"$dir\"").append(WRAP)
                .append("cd $path\"/\"$dir").append(WRAP)
                .append("sh $dir\"-startup.sh\"").append(WRAP)
                .append("echo $dir\"-startup.sh执行中\"").append(WRAP)
                .append("sleep 20").append(WRAP)
                .append("done").append(WRAP);
        String startAll = sb.toString();
        //生成
        FileWriter fileWriter = null;
        try {
            //创建路径
            File file1 = new File(Constants.BASE_OUTPUT_PATH );
            if (!file1.exists()) {
                file1.mkdir();
            }
            //写入文件
            File file = new File(Constants.BASE_OUTPUT_PATH + "all-service-startup.sh");
            fileWriter = new FileWriter(file);
            fileWriter.write(startAll);
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileWriter != null) {
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void createMoveStartupShellAll(ModelDomain modelDomain, HttpServletResponse httpServletResponse) {
        // 生成启动模块目录
        List<String> modelList = modelDomain.getModel();
        StringBuilder sb = new StringBuilder();
        for (String model :
                modelList) {
            if (sb.length() == 0) {
                sb.append(model);
            } else {
                sb.append(" ").append(model);
            }
        }
        String dirNames = sb.toString();
        sb.setLength(0);
        //生成启动脚本
        /**
         * #!/bin/bash
         * path=/u01/yljhalm/yljhalm-backend
         * workdir=$(cd $(dirname $0); pwd)
         * dirnames=(hzero-register hzero-gateway hzero-admin hzero-oauth hzero-iam hzero-platform hzero-file hzero-message hzero-report hzero-scheduler hzero-workflow halm-atn halm-mdm halm-mmt halm-mtc halm-platform halm-ppm)
         * for dir in ${dirnames[@]}
         * do
         * path1=$path/$dir
         * #准备目录
         * if [ ! -d $path1 ]
         * then
         * mkdir $path1
         * echo "$path1目录创建"
         * else
         * echo "$path1目录已存在"
         * fi
         * #准备移动文件
         * path2=$workdir/$dir
         * file2=$path1/$dir"-startup.sh"
         * if [ ! -f $file2 ]
         * then
         * echo "$path2-startup.sh文件准备移动"
         * mv $path2"-startup.sh" $path1
         * else
         * echo "$file2文件已经存在"
         * fi
         * done
         */
        sb.append("#!/bin/bash").append(WRAP)
                .append("path=").append(modelDomain.getPath()).append(WRAP)
                .append("workdir=$(cd $(dirname $0); pwd)").append(WRAP)
                .append("dirnames=(").append(dirNames).append(")").append(WRAP)
                .append("for dir in ${dirnames[@]}").append(WRAP)
                .append("do").append(WRAP)
                .append("path1=$path/$dir").append(WRAP)
                .append("#准备目录").append(WRAP)
                .append("if [ ! -d $path1 ]").append(WRAP)
                .append("then").append(WRAP)
                .append("mkdir $path1").append(WRAP)
                .append("echo $path1目录创建").append(WRAP)
                .append("else").append(WRAP)
                .append("echo \"$path1目录已存在\"").append(WRAP)
                .append("fi").append(WRAP)
                .append("#准备移动文件").append(WRAP)
                .append("path2=$workdir/$dir").append(WRAP)
                .append("file1=$path2\"-startup.sh\"").append(WRAP)
                .append("file2=$path1/$dir\"-startup.sh\"").append(WRAP)
                .append("if [ ! -f $file2 ]").append(WRAP)
                .append("then").append(WRAP)
                .append("echo \"$file2文件准备移动\"").append(WRAP)
                .append("mv $file1 $path1").append(WRAP)
                .append("else").append(WRAP)
                .append("echo \"$file2文件已经存在\"").append(WRAP)
                .append("fi").append(WRAP)
                .append("done").append(WRAP);
        String startAll = sb.toString();
        //生成
        FileWriter fileWriter = null;
        try {
            //创建路径
            File file1 = new File(Constants.BASE_OUTPUT_PATH );
            if (!file1.exists()) {
                file1.mkdir();
            }
            //写入文件
            File file = new File(Constants.BASE_OUTPUT_PATH + "move-all-startup.sh");
            fileWriter = new FileWriter(file);
            fileWriter.write(startAll);
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileWriter != null) {
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void createMoveShutdownShellAll(ModelDomain modelDomain, HttpServletResponse httpServletResponse) {
        // 生成启动模块目录
        List<String> modelList = modelDomain.getModel();
        StringBuilder sb = new StringBuilder();
        for (String model :
                modelList) {
            if (sb.length() == 0) {
                sb.append(model);
            } else {
                sb.append(" ").append(model);
            }
        }
        String dirNames = sb.toString();
        sb.setLength(0);
        //生成启动脚本
        sb.append("#!/bin/bash").append(WRAP)
                .append("path=").append(modelDomain.getPath()).append(WRAP)
                .append("workdir=$(cd $(dirname $0); pwd)").append(WRAP)
                .append("dirnames=(").append(dirNames).append(")").append(WRAP)
                .append("for dir in ${dirnames[@]}").append(WRAP)
                .append("do").append(WRAP)
                .append("path1=$path/$dir").append(WRAP)
                .append("#准备目录").append(WRAP)
                .append("if [ ! -d $path1 ]").append(WRAP)
                .append("then").append(WRAP)
                .append("mkdir $path1").append(WRAP)
                .append("echo $path1目录创建").append(WRAP)
                .append("else").append(WRAP)
                .append("echo \"$path1目录已存在\"").append(WRAP)
                .append("fi").append(WRAP)
                .append("#准备移动文件").append(WRAP)
                .append("path2=$workdir/$dir").append(WRAP)
                .append("file1=$path2\"-shutdown.sh\"").append(WRAP)
                .append("file2=$path1/$dir\"-shutdown.sh\"").append(WRAP)
                .append("if [ ! -f $file2 ]").append(WRAP)
                .append("then").append(WRAP)
                .append("echo \"$file2文件准备移动\"").append(WRAP)
                .append("mv $file1 $path1").append(WRAP)
                .append("else").append(WRAP)
                .append("echo \"$file2文件已经存在\"").append(WRAP)
                .append("fi").append(WRAP)
                .append("done").append(WRAP);
        String startAll = sb.toString();
        //生成
        FileWriter fileWriter = null;
        try {
            //创建路径
            File file1 = new File(Constants.BASE_OUTPUT_PATH );
            if (!file1.exists()) {
                file1.mkdir();
            }
            //写入文件
            File file = new File(Constants.BASE_OUTPUT_PATH + "move-all-shutdown.sh");
            fileWriter = new FileWriter(file);
            fileWriter.write(startAll);
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileWriter != null) {
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 创建关闭脚本
     *
     * @param modelDomain         接收对象
     * @param httpServletResponse 响应
     */
    @Override
    public void createShutDownShellAll(ModelDomain modelDomain, HttpServletResponse httpServletResponse) {
        List<String> modelList = modelDomain.getModel();
        StringBuilder sb = new StringBuilder();
        for (String model :
                modelList) {
            if (sb.length() == 0) {
                sb.append(model);
            } else {
                sb.append(" ").append(model);
            }
        }
        String dirNames = sb.toString();
        sb.setLength(0);
        sb.append("#!/bin/bash").append(WRAP)
                .append("path=").append(modelDomain.getPath()).append(WRAP)
                .append("dirnames=(").append(dirNames).append(")").append(WRAP)
                .append("for dir in ${dirnames[@]}").append(WRAP)
                .append("do").append(WRAP)
                .append("echo \"$dir\"").append(WRAP)
                .append("cd $path\"/\"$dir").append(WRAP)
                .append("sh $dir\"-shutdown.sh\"").append(WRAP)
                .append("done").append(WRAP);
        String startAll = sb.toString();
        //生成
        FileWriter fileWriter = null;
        try {
            File file1 = new File(Constants.BASE_OUTPUT_PATH );
            if (!file1.exists()) {
                file1.mkdir();
            }
            File file = new File(Constants.BASE_OUTPUT_PATH + "all-service-shutdown.sh");
            fileWriter = new FileWriter(file);
            fileWriter.write(startAll);
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileWriter != null) {
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void createReadMe() {
        StringBuilder sb = new StringBuilder();
        sb.append("1. 确保输入的服务根路径已经创建。例如：/u01/yljhalm/yljhalm-backend 目录").append(WRAP)
                .append("2. 勾选服务模块，点击下载（填写页面上的数据库连接信息，yml配置文件已经有了的，可以删除页面预留配置信息）").append(WRAP)
                .append("3. 将启动和关闭服务的压缩包上传到服务器路径下，例如：/u01/yljhalm/yljhalm-backend下").append(WRAP)
                .append("4. 执行unzip xxx.zip -d ./xxx 把脚本解压缩到xxx目录下").append(WRAP)
                .append("5. 进入解压目录，执行move-all开头的脚本，可以创建各个模块文件夹，并将各个模块的脚本移动至模块内部").append(WRAP)
                .append("6. 将all-service开头的脚本放到服务根目录，它是用来执行所有启动/关闭服务脚本，直接在服务根目录下执行即可").append(WRAP)
                .append("7. 如需拓展模块，在项目index.html文件中添加input模块即可").append(WRAP)
                .append("8. 如需修改启动脚本上限制的最大内存和最小内存，修改application.yml中的vm即可").append(WRAP);
        FileWriter fileWriter= null;

        try {
            File file1 = new File(Constants.BASE_OUTPUT_PATH );
            if (!file1.exists()) {
                file1.mkdir();
            }
            File file = new File(Constants.BASE_OUTPUT_PATH + "用前必读.txt");
            fileWriter = new FileWriter(file);
            fileWriter.write(sb.toString());
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (fileWriter!=null){
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 创建启动脚本
     * @param model 模块名
     * @return 启动脚本
     */
    private String createStartUp(String model,ModelDomain modelDomain) {
        Director director = new Director(defaultStartUp);
        if ("hzero-register".equals(model)) {
            return "#!/bin/bash\n" +
                    "source /etc/profile\n" +
                    "path= "+modelDomain.getPath()+"\n"+
                    "exec nohup java -Xmx1024m -Xms500m -DSPRING_PROFILES_ACTIVE=default  -jar target/hzero-register.jar > "+
                    modelDomain.getPath()+"/hzero-register.log 2>&1 &";
        } else {
            return director.createStarUpSh(model,modelDomain);
        }
    }

    /**
     * 创建脚本
     * @param model 模块名
     * @return 结束脚本
     */
    private String createShutdown(String model) {
        ShutdownBuilder defaultShutdown = new DefaultShutdown();
        Director director = new Director(defaultShutdown);
        return director.createShutdownSh(model);
    }

}
